﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using PJ.Data;

namespace PJ.Business
{
    /// <summary>
    /// <see cref="IBusinessObject"/> services interface
    /// </summary>
    public interface IBusinessObjectService : IDisposable
    {
        /// <summary>
        /// Gets the business object
        /// </summary>
        /// <param name="globalId">Object global id</param>
        /// <returns>The business object instance</returns>
        /// <exception cref="ArgumentNullException">If <paramref name="globalId"/> is <see langref="null"/> or empty.</exception>
        /// <exception cref="DataNotFoundException">If the business object with the given global id does not exist.</exception>
        IBusinessObject GetData(string globalId, GetDataMode mode);

        /// <summary>
        /// Gets a business object list
        /// </summary>
        /// <param name="globalIds">List of the GlobalIds of objects to fetch</param>
        /// <param name="mode">Fetch mode</param>
        /// <returns>The business object instances list</returns>
        /// <exception cref="ArgumentNullException">If <paramref name="globalId"/> is <see langref="null"/> or empty.</exception>
        /// <exception cref="DataNotFoundException">If the business object with the given global id does not exist and not in Find mode</exception>
        IEnumerable GetList(string[] globalIds, GetDataMode mode);


        /// <summary>
        /// Persists the business object.
        /// </summary>
        /// <param name="businessObject">Object to persist</param>
        /// <exception cref="ArgumentNullException">If <paramref name="businessObject"/> is <see langref="null"/>.</exception>
        /// <exception cref="ArgumentException">If <paramref name="businessObject"/> global id is <see langref="null"/>.</exception>
        void Persist(IBusinessObject businessObject);

        /// <summary>
        /// Persists the business object.
        /// </summary>
        /// <param name="businessObjectList">List of objects to persist</param>
        /// <exception cref="ArgumentNullExceptionList">If <paramref name="businessObjectList"/> is <see langref="null"/> or empty.</exception>
        /// <remarks>If the object global id is not defined, the object will be added</remarks>
        void Persist(IEnumerable businessObjectList);

        /// <summary>
        /// Persists the business object.
        /// </summary>
        /// <param name="businessObject">Object to persist</param>
        /// <returns>The persisted business object instance</returns>
        /// <exception cref="ArgumentNullException">If <paramref name="businessObject"/> is <see langref="null"/>.</exception>
        /// <remarks>If the object global id is not defined, the object will be added</remarks>
        IBusinessObject PersistAndGet(IBusinessObject businessObject);

        /// <summary>
        /// Checks if the business object exists.
        /// </summary>
        /// <param name="globalId">Object global id</param>
        /// <returns><see langref="true"/> if found else <see langref="false"/></returns>
        /// <exception cref="ArgumentNullException">If <paramref name="globalId"/> is <see langref="null"/> or empty.</exception>
        bool Exist(string globalId);

        /// <summary>
        /// Removes the business object from the business source
        /// </summary>
        /// <param name="globalId">Object global id</param>
        /// <exception cref="ArgumentNullException">If <paramref name="globalId"/> is <see langref="null"/> or empty.</exception>
        /// <exception cref="DataNotFoundException">If the business object with the given global id does not exist.</exception>
        void Delete(string globalId);

        /// <summary>
        /// Creates a new instance of the concrete class
        /// </summary>
        /// <returns>The business object instance</returns>
        IBusinessObject CreateNewItem();
    }

    /// <summary>
    /// <see cref="IBusinessObject"/> services interface
    /// </summary>
    /// <typeparam name="TIBusinessObject">Business <see cref="IBusinessObject">Object</see> interface instance type</typeparam>
    public interface IBusinessObjectService<TIBusinessObject> : IBusinessObjectService
        where TIBusinessObject : class, IBusinessObject
    {
        /// <summary>
        /// Gets the business object
        /// </summary>
        /// <param name="globalId">Object global id</param>
        /// <returns>The business object instance</returns>
        /// <exception cref="ArgumentNullException">If <paramref name="globalId"/> is <see langref="null"/> or empty.</exception>
        /// <exception cref="DataNotFoundException">If the business object with the given global id does not exist.</exception>
        new TIBusinessObject GetData(string globalId, GetDataMode mode);


        /// <summary>
        /// Gets a business object list
        /// </summary>
        /// <param name="globalIds">List of the GlobalIds of objects to fetch</param>
        /// <param name="mode">Fetch mode</param>
        /// <returns>The business object instance</returns>
        /// <exception cref="ArgumentNullException">If <paramref name="globalId"/> is <see langref="null"/> or empty.</exception>
        /// <exception cref="DataNotFoundException">If the business object with the given global id does not exist and not in Find mode</exception>
        new IEnumerable<TIBusinessObject> GetList(string[] globalIds, GetDataMode mode);


        /// <summary>
        /// Persists the business object and reloads it.
        /// </summary>
        /// <param name="businessObject">Object to persist</param>
        /// <returns>The persisted business object instance</returns>
        /// <exception cref="ArgumentNullException">If <paramref name="businessObject"/> is <see langref="null"/>.</exception>
        /// <exception cref="ArgumentException">If <paramref name="businessObject"/> global id is <see langref="null"/>.</exception>
        TIBusinessObject PersistAndGet(TIBusinessObject businessObject);

        /// <summary>
        /// Creates a new instance of the concrete class
        /// </summary>
        /// <returns>The business object instance</returns>
        new TIBusinessObject CreateNewItem();
    }
}
